package com.zzs.judge.service.impl;

import com.zzs.common.core.constant.RedisKeyConsts;
import com.zzs.common.core.entity.msg.CodeSubmitMessage;
import com.zzs.common.core.entity.mysql.CodeSubmitDO;
import com.zzs.common.core.enums.CodeSubmitStatus;
import com.zzs.common.core.util.SnowflakeUtil;
import com.zzs.common.redis.service.RedisService;
import com.zzs.judge.dao.mysql.UserSubmitMapper;
import com.zzs.judge.pojo.other.CompileResult;
import com.zzs.judge.pojo.other.RunResult;
import com.zzs.judge.service.ExeJavaCodeService;
import com.zzs.judge.service.JudgeCodeService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;

/**
 * @author zzs
 * @date 2025/03/28
 */
@Service
public class JudgeCodeServiceImpl implements JudgeCodeService {
    @Autowired
    private ExeJavaCodeService exeJavaCodeService;

    @Autowired
    private UserSubmitMapper userSubmitMapper;

    @Autowired
    private RedisService redisService;


    @Override
    public void judgeJavaCode(String containerId, CodeSubmitMessage codeSubmitMessage) {
        exeJavaCodeService.createJavaCodeFile(codeSubmitMessage);
        try {
            long start = System.currentTimeMillis();
            System.out.println("编译开始: " + start);
            CompileResult compileResult = exeJavaCodeService.compileJavaCode(containerId, codeSubmitMessage.getUserId());
            long end = System.currentTimeMillis();
            System.out.println("编译结束: " + end);
            System.out.println("编译时间: " + (end - start) + " ms");
            if (compileResult.getStatus() != CodeSubmitStatus.PASS.getStatus()) {
//            编译失败
                dealCompileError(codeSubmitMessage, compileResult);
            } else {
//            编译成功
                start = System.currentTimeMillis();
                System.out.println("运行开始: " + start);
                RunResult runResult = exeJavaCodeService.runJavaCode(containerId, codeSubmitMessage.getUserId());
                end = System.currentTimeMillis();
                System.out.println("运行结束: " + end);
                System.out.println("运行时间: " + (end - start) + " ms");
                dealRunResult(codeSubmitMessage, runResult);
            }
        } finally {
//            exeJavaCodeService.removeJavaCodeFile(codeSubmitMessage.getUserId());
//            删除用户判题是否进行的标志位
            redisService.removeKey(RedisKeyConsts.getJudgingKey(codeSubmitMessage.getUserId()));
        }
    }

    /**
     * 处理用户代码编译失败的逻辑
     * 当用户的代码提交后，如果编译失败，则调用此方法记录相关信息
     *
     * @param codeSubmitMessage 包含用户提交信息的数据传输对象，如用户ID、题目ID、代码语言和提交的代码
     * @param compileResult  编译失败的错误信息，用于记录在数据库中，帮助用户定位问题
     */
    private void dealCompileError(CodeSubmitMessage codeSubmitMessage, CompileResult compileResult) {
        // 获取当前时间，用于记录提交的时间
        LocalDateTime now = LocalDateTime.now();

        // 创建一个UserSubmitDO对象，用于保存用户提交的详细信息到数据库
        CodeSubmitDO codeSubmitDO = new CodeSubmitDO();

        BeanUtils.copyProperties(codeSubmitMessage, codeSubmitDO);
        BeanUtils.copyProperties(compileResult, codeSubmitDO);
        codeSubmitDO.setCreateTime(now);
        codeSubmitDO.setUpdateTime(now);
        String message = codeSubmitDO.getMessage();
        codeSubmitDO.setMessage(cleanErrorPath(message));
        // 调用Mapper的save方法保存用户提交记录到数据库
        userSubmitMapper.save(codeSubmitDO);
    }


    private void dealRunResult(CodeSubmitMessage codeSubmitMessage, RunResult runResult) {
        CodeSubmitDO codeSubmitDO = new CodeSubmitDO();
        BeanUtils.copyProperties(codeSubmitMessage, codeSubmitDO);
        BeanUtils.copyProperties(runResult, codeSubmitDO);
        LocalDateTime now = LocalDateTime.now();
        codeSubmitDO.setCreateTime(now);
        codeSubmitDO.setUpdateTime(now);
        String message = codeSubmitDO.getMessage();
        codeSubmitDO.setMessage(cleanErrorPath(message));
        userSubmitMapper.save(codeSubmitDO);
    }

    /**
     * 清理编译错误信息中的路径前缀，只保留文件名和行号等信息。
     * 例如：/usr/share/java/1904429967308099604/Solution.java:14: error: xxx
     *       → Solution.java:14: error: xxx
     *
     * @param rawErrorMsg 原始错误信息字符串
     * @return 清洗后的错误信息
     */
    public static String cleanErrorPath(String rawErrorMsg) {
        if (rawErrorMsg == null || rawErrorMsg.isEmpty()) {
            return "";
        }
        return rawErrorMsg.replaceAll("/usr/share/java/\\d+/", "");
    }

}
